/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package utils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

/**
 * 包含一些与微信交互的很常用的方法
 *
 * @author 王仲秋
 */
public class WeiXinUtil {

    /**
     * 使用认证后的认证凭证 code 到微信接口获取用户的基本信息 这些信息 不包含用户的个人信息
     *
     * @param code
     * @param secret
     * @param appid
     * @return
     */
//    public static WeiXinOauth2Entity getUserOpenId(String code, String secret, String appid) {
//        String strUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appid + "&secret=" + secret + "&code=" + code + "&grant_type=authorization_code";
//        ObjectMapper objectMapper = new ObjectMapper();
//        JsonNode atjson = null;
//        WeiXinOauth2Entity oauth2 = new WeiXinOauth2Entity();
//        try {
//            atjson = objectMapper.readTree(getHttpBackDomStr(strUrl));
//            oauth2.setAccessToken(atjson.get("access_token").getTextValue());
//            oauth2.setExpiresIn(atjson.get("expires_in").getIntValue());
//            oauth2.setOpenid(atjson.get("openid").getTextValue());
//            oauth2.setRefreshToken(atjson.get("refresh_token").getTextValue());
//            oauth2.setScope(atjson.get("scope").getTextValue());
//            JsonNode unionId = atjson.get("unionid");
//            if (unionId != null) {
//                oauth2.setUnionid(atjson.get("unionid").getTextValue());
//            }
//        } catch (JsonProcessingException e) {
//            // TODO Auto-generated catch block
//            e.printStackTrace();
//        } catch (IOException e) {
//            // TODO Auto-generated catch block
//            e.printStackTrace();
//        }
//        return oauth2;
//    }
//
//    /**
//     * 使用用的openid 和获取用户信息的凭证 access_token 进一步获取用户的个人信息
//     *
//     * @param oauth2Entity
//     * @return
//     */
//    public static WeiXinUserEntity getUserInf(WeiXinOauth2Entity oauth2Entity) {
//        ObjectMapper objectMapper = new ObjectMapper();
//        String infoUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s";
//        WeiXinUserEntity weiXinUserEntity = new WeiXinUserEntity();
//        try {
//            JsonNode ifjson = objectMapper.readTree(getHttpBackDomStr(String.format(infoUrl, oauth2Entity.getAccessToken(), oauth2Entity.getOpenid())));
//            weiXinUserEntity.setCity(ifjson.get("city").getTextValue());
//            weiXinUserEntity.setCountry(ifjson.get("country").getTextValue());
//            weiXinUserEntity.setHeadimgurl(ifjson.get("headimgurl").getTextValue());
//            weiXinUserEntity.setNickname(ifjson.get("nickname").getTextValue());
//            weiXinUserEntity.setOpenid(ifjson.get("openid").getTextValue());
//            JsonNode privilegeArray = ifjson.get("privilege");
//            JSONArray array = privilegeArray.
//            weiXinUserEntity.setPrivilege(privilegeArray.);
//            weiXinUserEntity.setSex(ifjson.get("sex").getIntValue());
//            JsonNode unionId = ifjson.get("unionid");
//            if (unionId != null) {
//                weiXinUserEntity.setUnionid(ifjson.get("unionid").getTextValue());
//            }
//        } catch (IOException ex) {
//        }
//        return weiXinUserEntity;
//    }
//
//    /**
//     * 微信网页开发获取用户信息的接口
//     *
//     * @param accessToken
//     * @param openId
//     * @return
//     */
//    protected static WeiXinUserEntity getUserInf(String accessToken, String openId) {
//        ObjectMapper objectMapper = new ObjectMapper();
//        String infoUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s";
//        WeiXinUserEntity weiXinUserEntity = new WeiXinUserEntity();
//        try {
//            JsonNode ifjson = objectMapper.readTree(getHttpBackDomStr(String.format(infoUrl, accessToken, openId)));
//            weiXinUserEntity.setCity(ifjson.get("city").getTextValue());
//            weiXinUserEntity.setCountry(ifjson.get("country").getTextValue());
//            weiXinUserEntity.setHeadimgurl(ifjson.get("headimgurl").getTextValue());
//            weiXinUserEntity.setNickname(ifjson.get("nickname").getTextValue());
//            weiXinUserEntity.setOpenid(ifjson.get("openid").getTextValue());
//            weiXinUserEntity.setPrivilege(ifjson.get("privilege").getTextValue());
//            weiXinUserEntity.setSex(ifjson.get("sex").getIntValue());
//            JsonNode unionId = ifjson.get("unionid");
//            if (unionId != null) {
//                weiXinUserEntity.setUnionid(ifjson.get("unionid").getTextValue());
//            }
//        } catch (IOException ex) {
//            ex.printStackTrace();
//        }
//        return weiXinUserEntity;
//    }

    /**
     * 使用get方式访问一个url并获取返回的数据流 转换成字符串
     *
     * @param urlStr
     * @return
     */
    public static String getHttpBackDomStr(String urlStr) {
        StringBuilder sb = new StringBuilder();
        try {
            URL url = new URL(urlStr);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setConnectTimeout(10000);// 设置连接主机超时（单位：毫秒）
            conn.setReadTimeout(10000);// 设置从主机读取数据超时（单位：毫秒）		
            conn.connect();
            BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
            String str;
            while ((str = br.readLine()) != null) {
                sb.append(str);
            }
            br.close();
            conn.disconnect();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            //e.printStackTrace();
        }
        return sb.toString();
    }

    /**
     * 将单层的xml字符装换成map 如果不能解析成xml那么返回空null 如果没有节点返回空map 对象
     *
     * @param xmlStr
     * @throws java.lang.Exception
     * @return
     */
    public static Map<String, String> xmlStrToMap(String xmlStr) {
        // 将解析结果存储在HashMap中
        Map<String, String> map = new HashMap<String, String>();
        Document document = null;
        try {
            document = DocumentHelper.parseText(xmlStr);
        } catch (DocumentException ex) {
            return null;
        }
        // 得到xml根元素
        Element root = document.getRootElement();
        // 得到根元素的所有子节点
        List<Element> elementList = root.elements();
        // 遍历所有子节点
        for (Element e : elementList) {
            map.put(e.getName(), e.getText());
        }
        // 释放资源
        return map;
    }

    /**
     * 验证签名 微信公众号开发使用 验证签名的
     *
     * @param signature
     * @param timestamp
     * @param nonce
     * @param token
     * @return
     */
    public static boolean checkSignature(String signature, String timestamp, String nonce, String token) {
        String[] arr = new String[]{token, timestamp, nonce};
        // 将token、timestamp、nonce三个参数进行字典序排序  
        Arrays.sort(arr);
        StringBuilder content = new StringBuilder();
        for (String arr1 : arr) {
            content.append(arr1);
        }
        MessageDigest md = null;
        String tmpStr = null;
        try {
            md = MessageDigest.getInstance("SHA-1");
            // 将三个参数字符串拼接成一个字符串进行sha1加密  
            byte[] digest = md.digest(content.toString().getBytes());
            tmpStr = byteToStr(digest);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        content = null;
        // 将sha1加密后的字符串可与signature对比，标识该请求来源于微信  
        return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false;
    }

    /**
     * 将字节数组转换为十六进制字符串
     *
     * @param digest
     * @return
     */
    private static String byteToStr(byte[] digest) {
        // TODO Auto-generated method stub
        String strDigest = "";
        for (int i = 0; i < digest.length; i++) {
            strDigest += byteToHexStr(digest[i]);
        }
        return strDigest;
    }

    /**
     * 将字节转换为十六进制字符串
     *
     * @param b
     * @return
     */
    private static String byteToHexStr(byte b) {
        // TODO Auto-generated method stub
        char[] Digit = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
        char[] tempArr = new char[2];
        tempArr[0] = Digit[(b >>> 4) & 0X0F];
        tempArr[1] = Digit[b & 0X0F];
        String s = new String(tempArr);
        return s;
    }

}
